package com.aloha.springframework.aop.framework;

import com.aloha.springframework.aop.AdvisedSupport;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.aopalliance.aop.Advice;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @author DaiZhiHeng
 * @date 2023/7/10 15:19
 */
public abstract class AbstractDynamicAopProxy implements InvocationHandler, MethodInterceptor {

    protected final AdvisedSupport advised;

    public AbstractDynamicAopProxy(AdvisedSupport advised) {
        this.advised = advised;
    }

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        return doProxy(proxy, method, args);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return doProxy(proxy, method, args);
    }

    private Object doProxy(Object proxy, Method method, Object[] args) throws Throwable {
        // 被代理的对象
        Object target = advised.getTargetSource().getTarget();
        Class<?> targetClass = target.getClass();
        // 拦截器链
        List<Advice> chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

        // 无需代理
        if (chain == null || chain.isEmpty()) return method.invoke(target, args);

        // 执行JointPoint的方法
        ReflectiveMethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        return invocation.proceed();
    }
}
